import md5 from "md5";
import MessageObject from './messageObject';
const _pushMessage = Symbol('_pushMessage');
    
export class SendController {
    static instance = null;                                                                     // 发送器实例
    static messageArray = [];                                                                   // 通讯列表                            
    constructor(socket) {
        if (!SendController.instance) {
            SendController.instance = this;
            this.socket = socket;
            this.so = this.socket.so;
            this.messageObject = new MessageObject(socket);                                     // 消息类型集合
        }
        return SendController.instance;
    }
    /* 创建，添加到消息队列*/
    [_pushMessage](sign, data, fromMemberId, succCallback, failCallback) {
        /*创建消息主体*/
        const makeClientMsgPackage = (typeTitle, data, fromMemberId = 0) => {
            var arr = [{
                type: "talk",                                                       //消息类型
                keys: ["talk_id", "type", "content"]                                //必填字段
            },
            { type: "makeTemporaryTalk", keys: ["dialogueKey"] },
            {
                type: "login",                                                      //登录
                keys: ["key", "loginKey", "token", "sertype", "isForceLogin"],
            },
            { type: "heartbeat", keys: [], },
            { type: 'getTalkDetail', keys: ['talk_id'], },
            { type: 'refreshInEditSelfInfo', keys: [] },
            { type: 'addFriendUseTalkId', keys: ['talk_id'] },
            { type: 'addFriendUseMemberId', keys: ['member_id'] },
            { type: 'examineToFriend', keys: [] },
            { type: 'delFriend', keys: [] },
            { type: 'findFriendFromTel', keys: [] },
            { type: 'getSelfTalkList', keys: [] }
            ]
            const dataKeys = Object.keys(data);
            // 必填字段
            const messageKeyList = arr.find(item => { if (item.type == typeTitle) { return item; } })
            if (!messageKeyList) { return { code: 301, data: "消息类型未定义！" } }
            const key = messageKeyList.keys.find(key => { if (!dataKeys.includes(key)) { return key } })
            if (key) { return { code: 301, data: "缺失字段" + key } }
            var myDate = new Date();
            var outData = {
                head: {
                    po: 2,
                    ms: 1,
                    fromMemberId,
                    clientMsgId: "",
                    action: messageKeyList.type,
                    dateTime: myDate.toLocaleTimeString(),
                },
                body: {},
            };
            dataKeys.forEach(key => { outData["body"][key] = data[key]; })            //消息body 字段填充
            const md5String = md5(JSON.stringify(outData) + Date.now());
            outData["head"]["clientMsgId"] = fromMemberId + "_" + md5String;
            return { data: outData, code: 200 };
        }
        if (sign != "login") { if (fromMemberId == 0) { console.log("forMemberId为0，请登录！"); return { code: 301, data: "请登录！" } } }
        var content = makeClientMsgPackage(sign, data, fromMemberId)                                                                // 创建消息
        if (content.code != 200) { return { code: 301, data: content.data }; }
        content.data.client = {
            addTime: Date.now(),
            sendTime: '',
            sendStatus: 1,  //1 正在发送 2.发送失败 3. 发送成功
            sendNum: 0,
            succCallback: succCallback ? succCallback : '',                            //消息成功执行的回调函数
            failCallback: failCallback ? failCallback : ''                             //消息失败执行的回调函数
        }
        const messageData = JSON.parse(JSON.stringify(content));                                                                    //深拷贝
        //console.log(this.messageObject, content.data.head.action,11)
        this.messageObject[content.data.head.action].sendMessage(messageData.data);                                                 //talk 添加聊天记录操作
        SendController.messageArray.push(content);                                                                                  //添加到通讯队列
        return { code: 200, data: content };
    }
    /* 发送消息入口*/
    _sendMessage(clientMsgId) {
        this.so = this.socket.so
        const sendMessageArray = (content, count) => {
            let length = 4;
            if (count >= length) {
                if (content.client.sendStatus != 3) {
                    content.client.sendStatus = 2;
                    content.client.fail = true;
                    content.client.failCallback && content.client.failCallback(content);
                    this.socket.talkObject.changeMessageStatus(content.head.clientMsgId, 2)
                    console.log("消息发送失败！");
                }
            }
            if (content.client.sendStatus != 3) {
                content.client.sendNum++;
                // 删除client
                // const information = Object.assign({}, content);
                // delete information.client;
                this.so.send(JSON.stringify(content));
                console.log("消息发送次数：", content.client.sendNum)
                setTimeout(() => { sendMessageArray(content, count + 1) }, 1000);
            }
        }
        if (!this.so || this.so.readyState !== 1) { console.log("socket连接已断开！"); }
        const message = SendController.messageArray.find(message => { if (message.data.head.clientMsgId === clientMsgId) { return message } })
        sendMessageArray(message.data, 0);
    }
    /* 收到回执信息*/
    _getServerReceiptMsg(data) {
        if (data.head.action != "heartbeat") { console.log("收到回执", data) }
        // 改变消息队列的状态和发送时间
        //1.在通讯队列中找到该消息对象
        const message = SendController.messageArray.find(message => {                           // 改变消息的状态
            if (message.data.head.clientMsgId === data.head.clientMsgId) { return message; }
        });
        if (!message) { return }
        var client = message.data.client;
        client.sendStatus = 3;
        if (data.body.code != 200) { return client.failCallback && client.failCallback(data) }
        //2.改变用户历史消息状态
        if (data.head.action == 'talk') { this.socket.talkObject.changeMessageStatus(data.head.clientMsgId, 3) }
        const res = this.messageObject[data.head.action].receiptMsg(data);
        if (res.code === 200) { client.succCallback && client.succCallback(data); } else {
            console.log(res.data);
            client.failCallback && client.failCallback(res);
        }
    }
    /*发送服务器信息*/
    sendServerMsg(sign, content, toMemberId, succCallback, failCallback) {
        for (let i in arguments) {
            if (arguments[i] == '' || arguments[i] == undefined || arguments[i] == null) {
                console.log("sendServerMsg，第" + i + "个参数不能为空！");
            }
        }
        const data = this[_pushMessage](sign, content, toMemberId, succCallback, failCallback);
        if (data.code != 200) {
            console.log("消息创建失败！");
        }
        this._sendMessage(data.data.data.head.clientMsgId);
        return data
    }
}

